const { useState, useEffect, useRef } = React;

// 格式化时间到 YYYY-MM-DD HH:mm 格式供显示
function formatDate(iso) {
  const d = new Date(iso);
  return d.toLocaleString();
}

function getDaysBetween(start, end) {
  const days = [];
  const current = new Date(start);
  current.setHours(0, 0, 0, 0);
  const endDate = new Date(end);
  endDate.setHours(0, 0, 0, 0);
  
  while (current <= endDate) {
    days.push(new Date(current));
    current.setDate(current.getDate() + 1);
  }
  return days;
}

function formatDayHeader(date) {
  const options = { weekday: 'short', month: 'numeric', day: 'numeric' };
  return date.toLocaleDateString('zh-CN', options);
}

// 将时间段划分为若干区间，每个区间代表一天（如果第一天和最后一天为部分天则按实际时长）
function getDaySegments(start, end) {
  const segments = [];
  let current = new Date(start);
  
  // 获取第一天的结束时间点（下一天的0点）
  const firstDayEnd = new Date(current);
  firstDayEnd.setDate(current.getDate() + 1);
  firstDayEnd.setHours(0, 0, 0, 0);
  
  // 添加第一天（可能是部分天）
  if (current < firstDayEnd) {
    segments.push({ 
      start: new Date(current), 
      end: new Date(Math.min(firstDayEnd, end))
    });
  }
  
  // 设置 current 为下一天的开始
  current = new Date(firstDayEnd);
  
  while (current < end) {
    let nextMidnight = new Date(current);
    nextMidnight.setDate(current.getDate() + 1);
    nextMidnight.setHours(0, 0, 0, 0);
    
    if (nextMidnight > end) nextMidnight = end;
    segments.push({ start: new Date(current), end: nextMidnight });
    current = nextMidnight;
  }
  return segments;
}

// 添加修改预定窗口组件
function EditBookingModal({ booking, onClose, onUpdate }) {
  // 格式化日期时间为本地时区的 datetime-local 格式
  function formatDateTimeLocal(date) {
    const d = new Date(date);
    d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
    return d.toISOString().slice(0, 16);
  }

  const [startTime, setStartTime] = useState(booking ? formatDateTimeLocal(booking.start) : '');
  const [endTime, setEndTime] = useState(booking ? formatDateTimeLocal(booking.end) : '');

  const handleSubmit = (e) => {
    e.preventDefault();
    // 转换回 UTC 时间
    const start = new Date(startTime);
    const end = new Date(endTime);
    onUpdate({
      ...booking,
      start: start,
      end: end
    });
  };

  return (
    <div className="modal-overlay">
      <div className="modal-content">
        <h3>修改预定时间</h3>
        <form onSubmit={handleSubmit}>
          <div className="form-group">
            <label>开始时间：</label>
            <input
              type="datetime-local"
              value={startTime}
              onChange={(e) => setStartTime(e.target.value)}
            />
          </div>
          <div className="form-group">
            <label>结束时间：</label>
            <input
              type="datetime-local"
              value={endTime}
              onChange={(e) => setEndTime(e.target.value)}
            />
          </div>
          <div className="modal-buttons">
            <button type="submit">保存</button>
            <button type="button" onClick={onClose}>取消</button>
          </div>
        </form>
      </div>
    </div>
  );
}

function GanttChart({ 
  resourceId,
  bookings,
  startDate,
  endDate,
  onAddBooking,
  onDeleteBooking,
  onUpdateBooking,
  user,
  showPopup
}) {
  const [scale, setScale] = useState(1); // 缩放比例，1 表示默认大小
  const [selection, setSelection] = useState(null);
  const [isDragging, setIsDragging] = useState(false);
  const [contextMenu, setContextMenu] = useState(null);
  const timelineRef = useRef(null);
  const [message, setMessage] = useState('');
  const [editingBooking, setEditingBooking] = useState(null);
  const [resizing, setResizing] = useState(null);
  const containerRef = useRef(null);
  const [clickStartTime, setClickStartTime] = useState(null);
  const CLICK_THRESHOLD = 200; // 点击判定阈值（毫秒）
  const DOUBLE_CLICK_DELAY = 300; // 双击判定阈值（毫秒）
  const [editModalBooking, setEditModalBooking] = useState(null);
  const [lastClickTime, setLastClickTime] = useState(0);
  const [currentTime, setCurrentTime] = useState(new Date());

  // 计算常量
  const BASE_HOUR_WIDTH = 50; // 每小时的基本宽度（像素）
  const HOUR_WIDTH = BASE_HOUR_WIDTH * scale; // 实际显示的每小时宽度
  const MIN_SCALE = 0.15; // 调整最小缩放比例，使一周的时间能完整显示
  const MAX_SCALE = 3; // 最大缩放比例
  const msPerPixel = (60 * 60 * 1000) / HOUR_WIDTH; // 每像素代表的毫秒数

  // 计算总时间跨度（小时）
  const totalHours = (endDate - startDate) / (1000 * 60 * 60);
  // 计算时间轴总宽度
  const timelineWidth = totalHours * HOUR_WIDTH;

  // 添加实时更新当前时间的效果
  useEffect(() => {
    // 每分钟更新一次当前时间
    const timer = setInterval(() => {
      setCurrentTime(new Date());
    }, 60000); // 60000ms = 1分钟

    return () => clearInterval(timer);
  }, []);

  // 处理鼠标滚轮事件
  function handleWheel(e) {
    e.preventDefault();
    const delta = e.deltaY > 0 ? -0.1 : 0.1; // 滚轮向下缩小，向上放大
    setScale(prevScale => {
      const newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, prevScale + delta));
      return newScale;
    });
  }

  // 生成时间刻度标记
  function generateTimeMarks() {
    const marks = [];
    let current = new Date(startDate);
    current.setMinutes(0, 0, 0);
    const endTime = new Date(endDate);
    endTime.setMinutes(0, 0, 0);
    endTime.setHours(endTime.getHours() + 1);

    while (current <= endTime) {
      marks.push(new Date(current));
      current = new Date(current.getTime() + 60 * 60 * 1000);
    }
    return marks;
  }

  // 时间转像素位置
  function timeToPosition(time) {
    const timeDiff = new Date(time) - new Date(startDate);
    const hours = timeDiff / (60 * 60 * 1000);
    return hours * HOUR_WIDTH;
  }

  // 像素位置转时间
  function positionToTime(position) {
    const hours = position / HOUR_WIDTH;
    const timestamp = new Date(startDate).getTime() + Math.round(hours * 60 * 60 * 1000);
    return new Date(timestamp);
  }

  // 处理鼠标按下事件
  function handleMouseDown(e) {
    if (e.button !== 0) return; // 只响应左键
    if (!user) return; // 未登录用户不能预订
    if (!timelineRef.current) return;
    const rect = timelineRef.current.getBoundingClientRect();
    const startX = e.clientX - rect.left;
    const startTime = positionToTime(startX);
    setSelection({
      start: startTime,
      end: startTime
    });
    setIsDragging(true);
    e.preventDefault(); // 防止文本选择
  }

  // 处理鼠标移动事件
  function handleMouseMove(e) {
    if (!isDragging || !timelineRef.current || !selection) return;
    // 检查鼠标是否在时间轴容器内
    const containerRect = containerRef.current.getBoundingClientRect();
    if (e.clientY < containerRect.top || e.clientY > containerRect.bottom) {
      return;
    }
    const rect = timelineRef.current.getBoundingClientRect();
    const currentX = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
    const currentTime = positionToTime(currentX);
    setSelection(prev => ({
      start: prev?.start || currentTime,
      end: currentTime
    }));
    e.preventDefault();
  }

  // 处理鼠标松开事件
  function handleMouseUp(e) {
    console.log('Mouse up event triggered', { isDragging, selection });
    if (!isDragging || !selection?.start || !selection?.end) return;
    
    // 检查鼠标是否在时间轴容器内
    const containerRect = containerRef.current.getBoundingClientRect();
    console.log('Container bounds:', {
      top: containerRect.top,
      bottom: containerRect.bottom,
      mouseY: e.clientY
    });
    if (e.clientY < containerRect.top || e.clientY > containerRect.bottom) {
      console.log('Mouse outside container bounds');
      setSelection(null);
      setIsDragging(false);
      return;
    }
    
    setIsDragging(false);
    const { start, end } = selection;
    
    // 确保开始时间小于结束时间
    const newStart = new Date(Math.min(start, end));
    const newEnd = new Date(Math.max(start, end));
    
    console.log('Time range selected:', {
      start: newStart,
      end: newEnd,
      duration: Math.round(Math.abs(newEnd - newStart) / (60 * 1000)) + ' minutes'
    });

    // 检查最小预定时长（10分钟）
    const now = new Date();
    if (Math.abs(newEnd - newStart) < 10 * 60 * 1000) {
      showPopup('预订时间段必须至少10分钟', 'error');
      setSelection(null);
      return;
    }

    // 检查是否在允许的时间范围内
    const endLimit = new Date(now);
    endLimit.setDate(now.getDate() + 7);

    if (newStart < now) {
      showPopup('不能预订过去的时间', 'error');
      setSelection(null);
      return;
    }
    
    if (newEnd > endLimit) {
      showPopup('只能预订未来7天内的时间', 'error');
      setSelection(null);
      return;
    }

    // 检查是否与现有预订重叠
    const hasOverlap = bookings.some(booking => 
      booking.resourceId === resourceId &&
      booking.start < newEnd &&
      booking.end > newStart
    );
    
    if (hasOverlap) {
      showPopup('选择的时间段与现有预订重叠', 'error');
      setSelection(null);
      return;
    }

    // 所有检查通过，创建预订
    console.log('Creating booking:', {
      start: newStart,
      end: newEnd,
      duration: Math.round(Math.abs(newEnd - newStart) / (60 * 1000)) + ' minutes'
    });
    
    // 确保 onAddBooking 被调用
    if (typeof onAddBooking === 'function') {
      console.log('Calling onAddBooking');
      onAddBooking({
        start: newStart,
        end: newEnd,
        clearSelection: () => setSelection(null)
      });
    } else {
      console.error('onAddBooking is not a function');
      setSelection(null);
    }
  }

  // 处理右键菜单
  function handleContextMenu(e, booking) {
    e.preventDefault();
    setContextMenu({
      x: e.clientX,
      y: e.clientY,
      booking
    });
  }

  // 添加预订块的工具提示内容
  function getBookingTooltip(booking) {
    const start = new Date(booking.start);
    const end = new Date(booking.end);
    const duration = (end - start) / (60 * 1000); // 转换为分钟
    return `${booking.user}\n开始：${formatDate(booking.start)}\n结束：${formatDate(booking.end)}\n时长：${duration}分钟${user && booking.user === user.username ? '\n右键点击可删除' : ''}`;
  }

  // 修改预订块拖拽调整的处理函数
  function handleResizeStart(e, booking, edge) {
    e.stopPropagation();
    setResizing({ booking, edge });
  }

  // 修改点击处理函数，分为按下和抬起两个阶段
  function handleBookingMouseDown(e, booking) {
    // 如果不是当前用户的预订，不允许编辑
    if (!user || booking.user !== user.username) return;
    
    // 如果是右键点击，不处理（因为右键有删除菜单）
    if (e.button !== 0) return;
    
    // 记录点击开始时间
    setClickStartTime(Date.now());
    
    e.stopPropagation();  // 阻止事件冒泡
    e.preventDefault();    // 阻止默认行为
  }

  function handleBookingMouseUp(e, booking) {
    if (!clickStartTime) return;
    
    const clickDuration = Date.now() - clickStartTime;
    setClickStartTime(null);
    
    // 检查是否是双击
    const now = Date.now();
    if (clickDuration < CLICK_THRESHOLD && !resizing) {
      if (now - lastClickTime < DOUBLE_CLICK_DELAY) {
        // 双击，打开修改窗口
        setEditModalBooking(booking);
      } else {
        // 单击，设置编辑状态
        setEditingBooking(booking);
      }
      setLastClickTime(now);
    }
    
    e.stopPropagation();
  }

  // 处理拖拽过程
  function handleResizeMove(e) {
    if (!resizing) return;
    const rect = timelineRef.current.getBoundingClientRect();
    const currentX = e.clientX - rect.left;
    const newTime = positionToTime(currentX);
    
    const { booking, edge } = resizing;
    const updatedBooking = { ...booking };
    
    if (edge === 'start') {
      updatedBooking.start = newTime;
    } else {
      updatedBooking.end = newTime;
    }
    
    setEditingBooking(updatedBooking);
  }

  // 处理拖拽结束
  function handleResizeEnd() {
    if (resizing && editingBooking) {
      const { start, end } = editingBooking;
      const now = new Date();
      
      // 验证时间范围
      if (Math.abs(end - start) < 10 * 60 * 1000) {
        showPopup('预订时间段必须至少10分钟', 'error');
        setResizing(null);
        setEditingBooking(null);
        return;
      }

      if (new Date(start) < now) {
        showPopup('不能预订过去的时间', 'error');
        setResizing(null);
        setEditingBooking(null);
        return;
      }

      const endLimit = new Date(now);
      endLimit.setDate(now.getDate() + 7);
      if (new Date(end) > endLimit) {
        showPopup('只能预订未来7天内的时间', 'error');
        setResizing(null);
        setEditingBooking(null);
        return;
      }

      // 检查是否与其他预订重叠
      const hasOverlap = bookings.some(booking => {
        if (booking.id === editingBooking.id) return false; // 跳过当前编辑的预订
        const bookingStart = new Date(booking.start);
        const bookingEnd = new Date(booking.end);
        return new Date(start) < bookingEnd && bookingStart < new Date(end);
      });

      if (hasOverlap) {
        showPopup('修改后的时间段与其他预订重叠', 'error');
        setResizing(null);
        setEditingBooking(null);
        return;
      }

      // 所有验证通过，更新预订
      onUpdateBooking(editingBooking);
    }
    setResizing(null);
    setEditingBooking(null);
  }

  // 在 GanttChart 组件中添加点击处理函数
  function handleBookingClick(e, booking) {
    // 如果不是当前用户的预订，不允许编辑
    if (!user || booking.user !== user.username) return;
    
    // 如果是右键点击，不处理（因为右键有删除菜单）
    if (e.button !== 0) return;
    
    e.stopPropagation();
    setEditingBooking(booking);
  }

  // 处理修改窗口的更新
  const handleModalUpdate = (updatedBooking) => {
    // 先验证时间
    const start = new Date(updatedBooking.start);
    const end = new Date(updatedBooking.end);
    const now = new Date();
    
    // 验证时间范围
    if (Math.abs(end - start) < 10 * 60 * 1000) {
      showPopup('预订时间段必须至少10分钟', 'error');
      return;
    }

    if (start < now) {
      showPopup('不能预订过去的时间', 'error');
      return;
    }

    const endLimit = new Date(now);
    endLimit.setDate(now.getDate() + 7);
    if (end > endLimit) {
      showPopup('只能预订未来7天内的时间', 'error');
      return;
    }

    // 检查是否与其他预订重叠
    const hasOverlap = bookings.some(booking => {
      if (booking.id === updatedBooking.id) return false; // 跳过当前编辑的预订
      const bookingStart = new Date(booking.start);
      const bookingEnd = new Date(booking.end);
      return start < bookingEnd && bookingStart < end;
    });

    if (hasOverlap) {
      showPopup('修改后的时间段与其他预订重叠', 'error');
      return;
    }

    // 所有验证通过，更新预订
    onUpdateBooking(updatedBooking)
      .then(() => {
        setEditModalBooking(null); // 成功后关闭窗口
      })
      .catch(error => {
        showPopup(error.message, 'error');
      });
  };

  useEffect(() => {
    if (isDragging) {
      // 只在拖拽时添加全局事件监听
      console.log('Adding mouse event listeners');
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      return () => {
        console.log('Removing mouse event listeners');
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
    }
  }, [isDragging, selection]);

  // 添加其他必要的事件监听器
  useEffect(() => {
    // 处理右键菜单关闭
    document.addEventListener('click', () => setContextMenu(null));
    
    // 处理缩放
    const timeline = timelineRef.current;
    if (timeline) {
      timeline.addEventListener('wheel', handleWheel, { passive: false });
    }
    
    return () => {
      document.removeEventListener('click', () => setContextMenu(null));
      if (timeline) {
        timeline.removeEventListener('wheel', handleWheel);
      }
    };
  }, []);

  // 处理预订块拖拽调整
  useEffect(() => {
    if (resizing) {
      document.addEventListener('mousemove', handleResizeMove);
      document.addEventListener('mouseup', handleResizeEnd);
      return () => {
        document.removeEventListener('mousemove', handleResizeMove);
        document.removeEventListener('mouseup', handleResizeEnd);
      };
    }
  }, [resizing]);

  // 处理点击外部区域
  useEffect(() => {
    function handleClickOutside(e) {
      // 如果点击的不是预定块或其子元素
      if (!e.target.closest('.booking-block')) {
        setEditingBooking(null);
      }
    }

    // 添加全局点击事件监听
    document.addEventListener('click', handleClickOutside);

    // 清理函数
    return () => {
      document.removeEventListener('click', handleClickOutside);
    };
  }, []);

  return (
    <div className="gantt-container">
      <div className="gantt-header">
        <div className="help-text">
          拖拽选择时间段进行预订（最小10分钟），使用鼠标滚轮进行缩放（当前缩放比例：{Math.round(scale * 100)}%）；
          <br />
          右键点击预订进行删除，双击预订进行编辑；
        </div>
      </div>

      <div className="timeline-container" style={{ '--scale': scale }} ref={containerRef}>
        <div className="timeline-header">
          {getDaySegments(startDate, endDate).map((segment, index) => {
            const hours = (segment.end - segment.start) / (60 * 60 * 1000);
            return (
              <div key={index} className="day" style={{ width: `${hours * HOUR_WIDTH}px` }}>
                {formatDayHeader(segment.start)}
              </div>
            );
          })}
        </div>

        <div className="time-scale">
          {generateTimeMarks().map((time, index) => (
            <div
              key={index}
              className="time-mark"
              style={{ left: `${timeToPosition(time)}px` }}
            >
              {time.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
            </div>
          ))}
        </div>

        <div
          className="timeline"
          ref={timelineRef}
          onMouseDown={handleMouseDown}
          style={{ width: `${timelineWidth}px` }}
        >
          <div className="time-grid">
            {generateTimeMarks().map((time, index) => (
              <div
                key={index}
                className="grid-line"
                style={{ 
                  left: `${timeToPosition(time) - (time.getHours() === 0 ? 1 : 0)}px`,
                  borderLeft: time.getHours() === 0 ? '2px solid #ddd' : '1px dashed #ddd'
                }}
              >
                <div className="hour-label">
                  {time.getHours().toString().padStart(2, '0')}:00
                </div>
              </div>
            ))}
          </div>

          {bookings.map(booking => (
            <div
              key={booking.id}
              className={`booking-block ${user && booking.user === user.username ? 'deletable' : ''} ${editingBooking?.id === booking.id ? 'editing' : ''}`}
              style={{
                left: `${timeToPosition(new Date(editingBooking?.id === booking.id ? editingBooking.start : booking.start))}px`,
                width: `${timeToPosition(new Date(editingBooking?.id === booking.id ? editingBooking.end : booking.end)) - timeToPosition(new Date(editingBooking?.id === booking.id ? editingBooking.start : booking.start))}px`
              }}
              onMouseDown={(e) => handleBookingMouseDown(e, booking)}
              onMouseUp={(e) => handleBookingMouseUp(e, booking)}
              onContextMenu={(e) => user && booking.user === user.username && handleContextMenu(e, booking)}
              title={getBookingTooltip(booking)}
            >
              <div className="booking-content">
                <div className="booking-user">{booking.user}</div>
                <div className="booking-time">
                  {new Date(booking.start).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
                  {' - '}
                  {new Date(booking.end).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
                </div>
              </div>
              {user && booking.user === user.username && (
                <>
                  <div
                    className="resize-handle left"
                    onMouseDown={(e) => handleResizeStart(e, booking, 'start')}
                  />
                  <div
                    className="resize-handle right"
                    onMouseDown={(e) => handleResizeStart(e, booking, 'end')}
                  />
                </>
              )}
            </div>
          ))}

          {selection?.start && selection?.end && (
            <div
              className="selection-area"
              style={{
                left: `${Math.min(timeToPosition(selection.start), timeToPosition(selection.end))}px`,
                width: `${Math.abs(timeToPosition(selection.end) - timeToPosition(selection.start))}px`
              }}
            />
          )}

          {/* 添加当前时间线 */}
          {currentTime >= startDate && currentTime <= endDate && (
            <div 
              className="current-time-line"
              style={{ 
                left: `${timeToPosition(currentTime)}px`,
              }} 
            />
          )}
        </div>
      </div>

      {/* 选择时间提示信息 */}
      {selection?.start && selection?.end && (
        <div className="selection-info">
          <strong>当前选择：</strong>
          {formatDate(selection.start)} - {formatDate(selection.end)}
          <span className="duration">
            时长：{Math.round(Math.abs(selection.end - selection.start) / (60 * 1000))}分钟
          </span>
        </div>
      )}

      {contextMenu && (
        <div
          className="context-menu"
          style={{ left: contextMenu.x, top: contextMenu.y }}
        >
          <div
            className="context-menu-item"
            onClick={() => {
              onDeleteBooking(contextMenu.booking.id);
              setContextMenu(null);
            }}
          >
            删除预订
          </div>
        </div>
      )}

      {/* 添加修改窗口 */}
      {editModalBooking && (
        <EditBookingModal
          booking={editModalBooking}
          onClose={() => setEditModalBooking(null)}
          onUpdate={handleModalUpdate}
        />
      )}
    </div>
  );
}

// 弹出提示组件
function PopupMessage({ message, type }) {
  return message ? (
    <div className={`popup-message ${type}`}>
      {message}
    </div>
  ) : null;
}

function App() {
  const [user, setUser] = useState(null);
  const [authMode, setAuthMode] = useState('login'); // 'login' 或 'register'
  const [loginUsername, setLoginUsername] = useState('');
  const [loginPassword, setLoginPassword] = useState('');
  const [registerUsername, setRegisterUsername] = useState('');
  const [registerPassword, setRegisterPassword] = useState('');
  const [bookings, setBookings] = useState([]);
  const [newStart, setNewStart] = useState('');
  const [newEnd, setNewEnd] = useState('');
  const [message, setMessage] = useState('');
  const [popupMessage, setPopupMessage] = useState({ text: '', type: 'success' });
  const [resources, setResources] = useState([]);
  const [selectedResource, setSelectedResource] = useState(null);
  const [newResourceName, setNewResourceName] = useState('');
  const [newResourceDesc, setNewResourceDesc] = useState('');

  // 获取当前时间和未来 7 天的日期
  const now = new Date();
  // 将当前时间设置为整点
  now.setMinutes(0, 0, 0);
  const fourteenDaysLater = new Date();
  // 将结束时间也设置为整点
  fourteenDaysLater.setMinutes(0, 0, 0);
  fourteenDaysLater.setDate(now.getDate() + 7);

  // 拉取预订数据
  function fetchBookings() {
    const query = `?start=${now.toISOString()}&end=${fourteenDaysLater.toISOString()}`;
    fetch('/api/bookings' + query)
      .then(res => res.json())
      .then(data => {
        // 按照开始时间排序
        data.sort((a, b) => new Date(a.start) - new Date(b.start));
        setBookings(data);
      })
      .catch(err => {
        console.error(err);
      });
  }

  // 获取资源列表
  const fetchResources = () => {
    fetch('/api/resources')
      .then(res => res.json())
      .then(setResources);
  };

  // 创建新资源
  const handleCreateResource = () => {
    fetch('/api/resources', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ 
        name: newResourceName,
        description: newResourceDesc 
      })
    })
    .then(res => res.json())
    .then(() => {
      fetchResources();
      setNewResourceName('');
      setNewResourceDesc('');
    });
  };

  // 删除资源
  const handleDeleteResource = (id) => {
    fetch(`/api/resources/${id}`, { method: 'DELETE' })
      .then(() => fetchResources());
  };

  useEffect(() => {
    fetch('/api/currentUser')
      .then(res => res.json())
      .then(data => {
        if (data.user) setUser(data.user);
      });
    fetchBookings();
    fetchResources();
  }, []);

  // 显示弹出提示的函数
  const showPopup = (text, type = 'success') => {
    setPopupMessage({ text, type });
    setTimeout(() => {
      setPopupMessage({ text: '', type: 'success' });
    }, 3000);
  };

  // 提交预订表单
  function handleSubmit(e) {
    e.preventDefault();
    if (!user) {
      setMessage('请先设置您的用户名。');
      return;
    }
    if (!newStart || !newEnd) {
      setMessage('请填写开始和结束时间。');
      return;
    }
    // 将 datetime-local 输入转换为 Date 对象后，再转换成 ISO 字符串
    const startIso = new Date(newStart).toISOString();
    const endIso = new Date(newEnd).toISOString();
    fetch('/api/bookings', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ start: startIso, end: endIso })
    })
      .then(async res => {
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.message || 'Error booking');
        }
        return res.json();
      })
      .then(data => {
        showPopup(`预订成功！ID: ${data.id}`, 'success');
        setNewStart('');
        setNewEnd('');
        fetchBookings();
      })
      .catch(err => {
        showPopup(err.message, 'error');
      });
  }

  // 删除预订
  function handleDelete(id) {
    fetch('/api/bookings/' + id, {
      method: 'DELETE',
      headers: { 'Content-Type': 'application/json' }
    })
      .then(async res => {
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.message || 'Error deleting booking');
        }
        return res.json();
      })
      .then(() => {
        showPopup('预订已删除', 'success');
        fetchBookings();
      })
      .catch(err => {
        showPopup(err.message, 'error');
      });
  }

  // 登录
  function handleLogin(e) {
    e.preventDefault();
    fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: loginUsername, password: loginPassword })
    })
      .then(async res => {
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.message || '登录失败');
        }
        return res.json();
      })
      .then(data => {
        setUser(data.user);
        showPopup(data.message, 'success');
        setLoginUsername('');
        setLoginPassword('');
      })
      .catch(err => {
        showPopup(err.message, 'error');
      });
  }

  // 注册
  function handleRegister(e) {
    e.preventDefault();
    fetch('/api/register', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: registerUsername, password: registerPassword })
    })
      .then(async res => {
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.message || '注册失败');
        }
        return res.json();
      })
      .then(data => {
        showPopup(data.message, 'success');
        setAuthMode('login');
        setRegisterUsername('');
        setRegisterPassword('');
      })
      .catch(err => {
        showPopup(err.message, 'error');
      });
  }

  // 登出
  function handleLogout() {
    fetch('/api/logout', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' }
    })
      .then(res => res.json())
      .then(data => {
        setUser(null);
        showPopup(data.message, 'success');
      });
  }

  // 在 App 组件中添加处理函数
  function handleAddBooking({ start, end, clearSelection }) {
    if (!selectedResource) {
      showPopup('请先选择资源', 'error');
      return;
    }
    
    const startIso = start.toISOString();
    const endIso = end.toISOString();
    
    fetch('/api/bookings', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        start: startIso,
        end: endIso,
        resourceId: selectedResource.id
      })
    })
    .then(async res => {
      console.log('Booking response status:', res.status);
      if (!res.ok) {
        const errorData = await res.json();
        throw new Error(errorData.message || '预订失败，请稍后重试');
      }
      return res.json();
    })
    .then(data => {
      console.log('Booking success:', data);
      const startTime = new Date(start);
      const endTime = new Date(end);
      const duration = Math.round(Math.abs(endTime - startTime) / (60 * 1000));
      showPopup(`预订成功！时间段：${formatDate(start)} - ${formatDate(end)}（${duration}分钟）`, 'success');
      fetchBookings();
      if (typeof clearSelection === 'function') {
        clearSelection();
      }
    })
    .catch(err => {
      console.error('Booking error details:', err);
      showPopup(err.message, 'error');
      fetchBookings();
      if (typeof clearSelection === 'function') {
        clearSelection();
      }
    });
  }

  // 更新预订
  function handleUpdateBooking(updatedBooking) {
    return fetch(`/api/bookings/${updatedBooking.id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        start: new Date(updatedBooking.start).toISOString(),
        end: new Date(updatedBooking.end).toISOString()
      })
    })
      .then(async res => {
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.message);
        }
        return res.json();
      })
      .then(() => {
        showPopup('预订更新成功！', 'success');
        fetchBookings();
      })
      .catch(err => {
        showPopup(err.message, 'error');
        throw err; // 继续抛出错误，让调用者知道更新失败
      });
  }

  if (!user) {
    return (
      <div className="container">
        <h1>独占资源预定</h1>
        <div className="auth-toggle">
          <button onClick={() => setAuthMode('login')}>登录</button>
          <button onClick={() => setAuthMode('register')}>注册</button>
        </div>
        {authMode === 'login' && (
          <form onSubmit={handleLogin}>
            <input 
              type="text" 
              placeholder="用户名" 
              value={loginUsername}
              onChange={(e) => setLoginUsername(e.target.value)} />
            <input 
              type="password" 
              placeholder="密码" 
              value={loginPassword}
              onChange={(e) => setLoginPassword(e.target.value)} />
            <button type="submit">登录</button>
          </form>
        )}
        {authMode === 'register' && (
          <form onSubmit={handleRegister}>
            <input 
              type="text" 
              placeholder="用户名" 
              value={registerUsername}
              onChange={(e) => setRegisterUsername(e.target.value)} />
            <input 
              type="password" 
              placeholder="密码" 
              value={registerPassword}
              onChange={(e) => setRegisterPassword(e.target.value)} />
            <button type="submit">注册</button>
          </form>
        )}
        <PopupMessage 
          message={popupMessage.text}
          type={popupMessage.type}
        />
      </div>
    );
  }

  return (
    <div className="container">
      <h1>独占资源预定</h1>
      <div className="user-info">
        <p>当前用户: <strong>{user.username}</strong> ({user.role})</p>
        <button onClick={handleLogout}>登出</button>
      </div>

      <PopupMessage 
        message={popupMessage.text}
        type={popupMessage.type}
      />

      {/* 管理员资源管理 */}
      {(user?.role === 'admin' || user?.isAdmin) && (
        <div className="resource-management">
          <h3 style={{ marginTop: '0' }}>资源管理</h3>
          <div className="add-resource">
            <input
              type="text"
              placeholder="资源名称"
              value={newResourceName}
              onChange={e => setNewResourceName(e.target.value)}
            />
            <input
              type="text"
              placeholder="资源描述"
              value={newResourceDesc}
              onChange={e => setNewResourceDesc(e.target.value)}
            />
            <button onClick={handleCreateResource}>添加资源</button>
          </div>
          <div className="resource-list">
            {resources.map(resource => (
              <div key={resource.id} className="resource-item">
                <span>{resource.name}</span>
                <button 
                  onClick={() => handleDeleteResource(resource.id)}
                  className="delete-resource"
                >
                  删除
                </button>
              </div>
            ))}
          </div>
        </div>
      )}

      <h2>预订时间表</h2>
      <div className="resource-selector">
        <select 
          value={selectedResource?.id || ''}
          onChange={e => setSelectedResource(
            resources.find(r => r.id === Number(e.target.value))
          )}
        >
          <option value="">请选择资源</option>
          {resources.map(resource => (
            <option key={resource.id} value={resource.id}>
              {resource.name}
            </option>
          ))}
        </select>
        {selectedResource && (
          <div className="selected-resource-info">
            当前选择：{selectedResource.name}（ID: {selectedResource.id}）
          </div>
        )}
      </div>

      {/* 修改GanttChart使用方式 */}
      {selectedResource && (
        <GanttChart
          resourceId={selectedResource.id}
          bookings={bookings.filter(b => b.resourceId === selectedResource.id)}
          startDate={now}
          endDate={fourteenDaysLater}
          onAddBooking={handleAddBooking}
          onDeleteBooking={handleDelete}
          onUpdateBooking={handleUpdateBooking}
          user={user}
          showPopup={showPopup}
        />
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('app')).render(<App />); 